var resBase = "game/res/";
var jsBase = "game/";
var state = "map";
var objList = {};
var imgList = {};
var modelList = {};
var cam = null;
var curmap = new Map();
curmap.data["0,0,1"] = [{objType: "_grass"}];
curmap.data["0,0,0"] = [{objType: "wall"}];
function preload() {
	print("Loading resources...");
	resXML = loadXML(resBase + "res.xml");
}

function setup() {
	initResources(resXML);
	mCreateCanvas(windowWidth, windowHeight, WEBGL);
	noStroke();
}

function draw() {
	mPush();
//	camera(0, -512, 500, 0, 0, 0, 0, 1, 0);
	orbitControl();
//	camera(0, -256, 500, 0, 0, 0, 0, 1, 0);
//	rotateZ(cam.Z);
//	rotateX(cam.X);
//	rotateY(cam.Y);
	background('#000');
	if (state == 'map') curmap.render();
	mPop();
}

function mouseMoved() {

}

function mousePress() {

}

// Lot //
/*var objNotFound = {};
var OBJMULT = 128;

function drawLot() {
	//mResetMatrix();
	if (!mapData) return;
	mPush();
	// draw ground
	var tex = imgList['grass'];
	if (tex && tex.image) {
		mRotateX(radians(90));
		texture(tex.image);
		mTranslate(0,OBJMULT/2,2);
		mPlane(mapSize*OBJMULT, mapSize*OBJMULT);
	}
	mPop();
	mPush();
	mTranslate(-(mapSize*OBJMULT)/2, 0, -(mapSize*OBJMULT)/2);
	for (var k in mapData) {
		var coord = k.split(',');
		var x = parseInt(coord[0]); var y = parseInt(coord[1]); var z = parseInt(coord[2]);
		var objid = (x * 65536) + (y * 256) + (z) + 1;
		var meta = mapData[k];
		var obj = objList[meta.object];
		if (!obj) {
			if (objNotFound[meta.object]) continue;
			objNotFound[meta.object] = true;
			print('WARNING: object not found: ' + meta.object);
			continue;
		}
		var MULT = OBJMULT;
		switch(obj.class) {
			case 'tile':
				var tex = imgList[obj.tile_texture];
				if (!tex) break;
				tex = tex.image;
				mPush();
				objDontCenterMe(obj);
				mTranslate(x*MULT,y*MULT,z*MULT);
				mRotateX(radians(90));
				if (tex) texture(tex); else fill('#eeeeee');
				//print(objid);
				mPlane(objid,MULT, MULT);
				//noLoop();
				mPop();
			break;
			case 'table':
				var model = modelList[obj.model];
				var hooks = {};
				hooks.old = this;
				hooks.mTranslate = function(x2, y2, z2) {
					if (!y2) y2 = 0;
					if (!z2) z2 = 0;
					objDontCenterMe(obj, true);
					hooks.old.mTranslate(x2+x*MULT,y2+y*MULT,z2+z*MULT);
				}
				if (!model) break;
				mPush();
				hooks.mTranslate(0,0,0);
				try { model.render.bind(hooks)(objid); } catch(e) {}
				mPop();
			break;
			case 'wall':
				var tex = imgList[obj.wall_texture];
				if (tex) tex = tex.image;
				mPush();
				mTranslate(x*MULT,y*MULT,z*MULT-MULT/2);
				mTranslate(0, 0, MULT);
				objDontCenterMe(obj);
				if (tex) texture(tex); else if (obj.fill) fill(obj.fill); else fill('#eeeeee');
				mPlane(objid,MULT, objectHeight(obj));
				mPop();
			break;
		}
	}
	mPop();
}*/

// --- //

function windowResized() {
  if (fullscreen()) {
    resizeCanvas(displayWidth, displayHeight);
  } else {
    resizeCanvas(windowWidth,windowHeight);
  }
  cursor();
}

// --- //
function objDontCenterMe(obj, notmodel) {
	mTranslate(objectWidth(obj)/2, notmodel ? -objectHeight(obj) : -objectHeight(obj)/2, OBJMULT);
}

function objectWidth(o) {
	if (o.width) return o.width * OBJMULT ;
	if (o.class=='tile') return OBJMULT;
	if (o.class=='table') return OBJMULT;
	if (o.class=='wall') return OBJMULT;
	return -1;
}

function objectHeight(o) {
	if (o.height) return o.height * OBJMULT ;
	if (o.class=='tile') return 1;
	if (o.class=='wall') return OBJMULT * 3;
	if (o.class=='table') return OBJMULT;
	return -1;
}

// --- //

function initResources(listXML) {
	initObjects(listXML);
	initImages(listXML);
	initModels(listXML);
	initIncludes(listXML);
}

function initIncludes(includeListXML) {
	var children = includeListXML.getChildren('include');
	for (var i = 0; i < children.length; i++) {
		(function(x) {
			loadXML(resBase + x, initResources);
		})(children[i].getString('path'))
	}
}

function initModels(modelListXML) {
	var children = modelListXML.getChildren('model');
	for (var i = 0; i < children.length; i++) {
		initSingleModel(children[i]);
	}
}

function initSingleModel(modelXML) {
	var cmds = [];
	var x = {};
	x.id = modelXML.getString('id');
	x.x = modelXML.getNum('width');
	x.y = modelXML.getNum('height');
	x.z = modelXML.getNum('depth');
	if (!x.x) x.x = 128;
	if (!x.y) x.y = 128;
	if (!x.z) x.z = 128;
	var children = modelXML.getChildren();
	var ARG_DB = {
		plane: ['mPlane','itemid','width','height'],
		box: ['mBox','itemid','width','height','depth'],
		sphere: ['mSphere','itemid','radius'],
		cone: ['mCone','itemid','radius','height'],
		cylinder: ['mCylinder','itemid','radius','height'],

		fill: ['fill','color'],
		stroke: ['stroke','color'],

		rotate: [ /* custom case */ ],
		scale: ['mScale','x','y','z'],
		translate: ['mTranslate','x','y','z'],
		texture: [ /* custom case */ ],

		group: [ /* custom case */ ]
	}
	var fn; fn = function(children) {
		cmds.push("mPush()");
		for (var i = 0; i < children.length; i++) {
			var instr = children[i];
			var params = [];
			var name = instr.getName().toLowerCase();
			if (name == '#text') continue;
			if (!ARG_DB[name]) throw "Exception: invalid model instruction: " + name;
			var args = ARG_DB[name];
			if (!args.length) {
				if (name == 'texture') {
					cmds.push("texture(imgList['" + instr.getString('image') + "'].image)")
				}
				if (name == 'rotate') {
					cmds.push("rotateX(" + instr.getNum('x') + ")")
					cmds.push("rotateY(" + instr.getNum('y') + ")")
					cmds.push("rotateZ(" + instr.getNum('z') + ")")
				}
				if (name == 'group') {
					fn(instr.getChildren());
				}
				continue;
			}
			var cmd = args[0] + "(";
			for (var x = 1; x < args.length; x++) {
				if (x > 1) cmd += ",";
				if (args[x] == "itemid") { cmd += "itemid"; continue; }
				cmd += JSON.stringify(instr.getString(args[x]));
			}
			cmd += ")";
			cmds.push(cmd);
		}
		cmds.push("mPop()")
	}; fn(children);
	x.render = new Function('itemid', cmds.join(';') + ';');
	modelList[x.id] = x;
}

function initImages(imgListXML) {
	var children = imgListXML.getChildren('image');
	for (var i = 0; i < children.length; i++) {
		initSingleImage(children[i]);
	}
}

function initSingleImage(xml) {
	var x = {};
	x.id = xml.getString('id');
	x.src = xml.getString('src');
	x.image = null;
	loadImage(resBase + x.src, function (img) {
		x.image = img; 
	});
	imgList[x.id] = x;
}

function initObjects(objListXML) {
	var children = objListXML.getChildren('object');
	for (var i = 0; i < children.length; i++) {
		initSingleObject(children[i]);
	}
}

function initSingleObject(xml, loadres) {
	var x = {};
	var attr = xml.listAttributes();
	for (var i = 0; i < attr.length; i++) {
		x[attr[i]] = xml.getString(attr[i]);
	}
	var children = xml.getChildren('action');
	for (var i = 0; i < children.length; i++) {
		var y = xmlElementToObject(children[i]);
		x[y.id] = y;
	}
	x.id = xml.getString('id');
	objList[x.id] = x;
}

// util //

function xmlElementToObject(xml) {
	var x = {};
	var attr = xml.listAttributes();
	for (var i = 0; i < attr.length; i++) {
		x[attr[i]] = xml.getString(attr[i]);
	}
	return x;
}
